package com.yonyou.pmclouds.plan.controller;

import com.alibaba.dubbo.config.annotation.Reference;
import com.yonyou.pmclouds.ApplicationConsts;
import com.yonyou.pmclouds.basecom.consts.BillTypeConst;
import com.yonyou.pmclouds.basecom.exception.BusinessException;
import com.yonyou.pmclouds.billtype.entity.BillTypeRefVO;
import com.yonyou.pmclouds.outter.nc.NcBillTypeCustomerQuery;
import com.yonyou.pmclouds.outter.nc.NcDeptCustomerQuery;
import com.yonyou.pmclouds.outter.user.UserInfoQuery;
import com.yonyou.pmclouds.outter.user.UserOperator;
import com.yonyou.pmclouds.plan.entity.ProjectPlanViewVO;
import com.yonyou.pmclouds.plan.plandriven.entity.NcDepartmentVO;
import com.yonyou.pmclouds.plan.plandriven.entity.NcDeptQueryParamVO;
import com.yonyou.pmclouds.plan.rmiitf.ProjectPlanMaintain;
import com.yonyou.pmclouds.plan.rmiitf.ProjectPlanQuery;
import com.yonyou.pmclouds.project.rmiitf.ProjectSimpleQuery;
import com.yonyou.pmclouds.team.rmiitf.ProjectRefWithTeamQuery;
import com.yonyou.pmclouds.team.rmiitf.TeamMemberQuery;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;

@RestController
@RequestMapping("/planAdjust1")
@Deprecated
public class PlanAdjustController {
    @Reference(version = ApplicationConsts.APPLICATION_VERSION)
    private ProjectPlanMaintain maintain;
    @Reference(version = ApplicationConsts.APPLICATION_VERSION)
    private ProjectPlanQuery query;
    @Reference(version = ApplicationConsts.APPLICATION_VERSION)
    private ProjectSimpleQuery projectSimpleQuery;
    @Reference(version = ApplicationConsts.APPLICATION_VERSION)
    private TeamMemberQuery teamMemberQuery;
    @Reference(version = ApplicationConsts.APPLICATION_VERSION)
    private ProjectRefWithTeamQuery refQuery;
    @Autowired
    private UserInfoQuery userInfoQuery;
    @Autowired
    private UserOperator userOperator;
    @Autowired
    private NcBillTypeCustomerQuery ncBillTypeCustomerQuery;
    @Autowired
    private NcDeptCustomerQuery ncDeptCustomerQuery;

    private static final String[] MANAGER_ID_FIELDS = {ProjectPlanViewVO.MANAGER};
    private static final String[] MANAGER_NAME_FIELDS = {ProjectPlanViewVO.MANAGER_NAME};
    private static final String[] USER_ID_FIELDS = {ProjectPlanViewVO.CREATOR};
    private static final String[] USER_NAME_FIELDS = {ProjectPlanViewVO.CREATOR_NAME};

    @GetMapping("/project")
    public ProjectPlanViewVO[] queryProject(@RequestParam("projectId") String projectId) throws BusinessException {
        ProjectPlanViewVO[] allVOs = query.queryLastViewByProject(projectId);
        if (ArrayUtils.isEmpty(allVOs)) {
            return allVOs;
        }
        setDependPlanName(allVOs);

        // 翻译单据类型、部门
        transAndFillViewVO(allVOs);

        String[] userFields = new String[]{ProjectPlanViewVO.MANAGER, ProjectPlanViewVO.CREATOR, ProjectPlanViewVO.PLAN_FINISHER};
        String[] userNameFields = new String[]{ProjectPlanViewVO.MANAGER_NAME, ProjectPlanViewVO.CREATOR_NAME,
                ProjectPlanViewVO.PLAN_FINISHER_NAME};
        userInfoQuery.tranUserInfoField(allVOs, userFields, userNameFields);
        Map<String, List<ProjectPlanViewVO>> childMap = genChildMap(allVOs);
        List<ProjectPlanViewVO> result = childMap.get(StringUtils.EMPTY);
        if (result == null) {
            return new ProjectPlanViewVO[0];
        } else {
            return result.toArray(new ProjectPlanViewVO[0]);
        }
    }

    @GetMapping("/history")
    public ProjectPlanViewVO[] history(@RequestParam("planId") String planId) throws BusinessException {
        ProjectPlanViewVO[] hisVOs = query.queryHistoryView(planId);
        if (ArrayUtils.isEmpty(hisVOs)) {
            return hisVOs;
        }
        setDependPlanName(hisVOs);

        // 翻译单据类型、部门
        transAndFillViewVO(hisVOs);

        String[] userFields = new String[]{ProjectPlanViewVO.MANAGER, ProjectPlanViewVO.CREATOR, ProjectPlanViewVO.PLAN_FINISHER};
        String[] userNameFields = new String[]{ProjectPlanViewVO.MANAGER_NAME, ProjectPlanViewVO.CREATOR_NAME,
                ProjectPlanViewVO.PLAN_FINISHER_NAME};
        userInfoQuery.tranUserInfoField(hisVOs, userFields, userNameFields);
        Map<String, List<ProjectPlanViewVO>> childMap = genChildMap(hisVOs);
        List<ProjectPlanViewVO> result = childMap.get(StringUtils.EMPTY);
        if (result == null) {
            return new ProjectPlanViewVO[0];
        } else {
            genCodeOfTree(null, result, childMap);
            Collections.reverse(result);

            return result.toArray(new ProjectPlanViewVO[0]);
        }
    }


    private void setDependPlanName(ProjectPlanViewVO[] allVOs){
        Map<String, ProjectPlanViewVO> planViewVOMap = new HashMap<String, ProjectPlanViewVO>();
        for(ProjectPlanViewVO vo : allVOs){
            planViewVOMap.put(vo.getPkPlan(), vo);
        }
        if(planViewVOMap != null){
            for(ProjectPlanViewVO vo : allVOs){
                if(StringUtils.isNotBlank(vo.getDependPlan())){
                    ProjectPlanViewVO viewVO = planViewVOMap.get(vo.getDependPlan());
                    if(viewVO != null){
                        vo.setDependPlanName(viewVO.getScode());
                    }
                }
            }
        }
    }

    private Map<String, List<ProjectPlanViewVO>> genChildMap(ProjectPlanViewVO[] allVOs) {
        // 构造树
        Map<String, List<ProjectPlanViewVO>> childMap = new HashMap<>();
        for (ProjectPlanViewVO vo : allVOs) {
            vo.setKey(vo.getPkPlan());
            String parent = vo.getPkParent();
            if (StringUtils.isEmpty(parent)) {
                parent = StringUtils.EMPTY;
            }
            List<ProjectPlanViewVO> children = childMap.get(parent);
            if (children == null) {
                children = new ArrayList<>();
                childMap.put(parent, children);
            }
            children.add(vo);
        }
        for (ProjectPlanViewVO vo : allVOs) {
            vo.setScode(null);
        }
        for (ProjectPlanViewVO vo : allVOs) {
            List<ProjectPlanViewVO> children = childMap.get(vo.getPkPlan());
            if (children != null) {
                vo.setChildren(children.toArray(new ProjectPlanViewVO[0]));
            }
        }
        return childMap;
    }

    private void genCodeOfTree(ProjectPlanViewVO parent, List<ProjectPlanViewVO> tree, Map<String, List<ProjectPlanViewVO>> childMap) {
        for (ProjectPlanViewVO plan : tree) {
            if (parent == null) {
                plan.setScode("0");
            } else if(StringUtils.isBlank(parent.getScode()) || parent.getScode().equals("0")){
                plan.setScode(Integer.toString(plan.getSeq()));
            } else{
                plan.setScode(parent.getScode() + '.' + plan.getSeq());
            }
            List<ProjectPlanViewVO> children = childMap.get(plan.getPkPlan());
            if (children != null && !children.isEmpty()) {
                // 递归应该不会出问题，最深20层
                genCodeOfTree(plan, children, childMap);
            }
            if(parent != null){
                if(parent.getStartDate() == null || (plan.getStartDate() != null && plan.getStartDate().compareTo(parent.getStartDate()) < 0)){
                    parent.setStartDate(plan.getStartDate());
                }
                if(plan.getProgress() == 100 && (parent.getEndDate() == null || (plan.getEndDate() != null && plan.getEndDate().compareTo(parent.getEndDate()) > 0))){
                    parent.setEndDate(plan.getEndDate());
                }
            }
        }
    }

    /**
     * 翻译单据类型、部门
     *
     * @param allVOs
     */
    private void transAndFillViewVO(ProjectPlanViewVO[] allVOs) throws BusinessException {
        Set<String> billTypeCodeSet = new HashSet<>();
        Set<String> pkDeptSet = new HashSet<>();
        for (ProjectPlanViewVO plan : allVOs) {
            if (plan.getChildCount() == 0) {
                if (StringUtils.isNotEmpty(plan.getRelatedBillType()))
                    billTypeCodeSet.add(plan.getRelatedBillType());
            }

            if (StringUtils.isNotEmpty(plan.getPkDepartment()))
                pkDeptSet.add(plan.getPkDepartment());
        }

        // 查询单据类型名称
        Map<String, String> billTypeCodeToName = null;
        if (billTypeCodeSet.size() > 0) {
            billTypeCodeToName = queryBillTypeName(billTypeCodeSet.toArray(new String[0]));
        }

        // 查询部门名称
        Map<String, String> pkDeptToName = null;
        if (pkDeptSet.size() > 0) {
            pkDeptToName = queryDepartmentName(pkDeptSet.toArray(new String[0]));
        }

        for (ProjectPlanViewVO vo : allVOs) {
            if (billTypeCodeToName != null && StringUtils.isNotEmpty(vo.getRelatedBillType())) {
                vo.setRelatedBillTypeName(billTypeCodeToName.get(vo.getRelatedBillType()));
            }

            if (pkDeptToName != null && StringUtils.isNotEmpty(vo.getPkDepartment())) {
                vo.setDepartmentName(pkDeptToName.get(vo.getPkDepartment()));
            }
        }
    }

    /**
     * 查询单据类型名称
     *
     * @param billTypeCodes
     * @return
     */
    private Map<String, String> queryBillTypeName(String[] billTypeCodes) throws BusinessException {
        // 是否查询NC单据类型
        boolean isQueryNcBillType = false;
        for (String billType : billTypeCodes) {
            if (!BillTypeConst.WORKSTART_BILLTYPE.equals(billType) && !BillTypeConst.COMPREHENSIVE_ACCEPTANCE_BILLTYPE.equals(billType)) {
                isQueryNcBillType = true;
                break;
            }
        }

        List<BillTypeRefVO> billTypeRefVOs = new ArrayList<>();
        billTypeRefVOs.add(new BillTypeRefVO(BillTypeConst.WORKSTART_BILLTYPE, BillTypeConst.WORKSTART_BILLTYPE_NAME));
        billTypeRefVOs.add(new BillTypeRefVO(BillTypeConst.COMPREHENSIVE_ACCEPTANCE_BILLTYPE,
                BillTypeConst.COMPREHENSIVE_ACCEPTANCE_BILLTYPE_NAME));
        if (isQueryNcBillType) {
            // 查询nc单据类型
            BillTypeRefVO[] ncBillTypeRefVO = ncBillTypeCustomerQuery.queryRelatedBillTypeForPlan();
            if (ArrayUtils.isNotEmpty(ncBillTypeRefVO)) {
                billTypeRefVOs.addAll(Arrays.asList(ncBillTypeRefVO));
            }
        }

        Map<String, String> result = new HashMap<>();
        Map<String, String> codeToName = new HashMap<>();
        for (BillTypeRefVO refVO : billTypeRefVOs) {
            codeToName.put(refVO.getCode(), refVO.getName());
        }

        for (String code : billTypeCodes) {
            result.put(code, codeToName.get(code));
        }

        return result;
    }

    /**
     * 查询部门名称
     *
     * @param pkDepartments
     * @return
     */
    private Map<String, String> queryDepartmentName(String[] pkDepartments) throws BusinessException {
        Map<String, String> result = new HashMap<>();
        List<NcDepartmentVO> ncDepartmentVOs = ncDeptCustomerQuery
                .queryDepartmentFromNc(new NcDeptQueryParamVO(null, null, Arrays.asList(pkDepartments)));

        if (CollectionUtils.isEmpty(ncDepartmentVOs))
            return result;

        for (NcDepartmentVO vo : ncDepartmentVOs) {
            result.put(vo.getPkDept(), vo.getName());
        }

        return result;
    }

}
